package com.hctforgreen.greenservice.utils;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.hctforgreen.greenservice.StartPwdActivity;
import com.hctforgreen.greenservice.model.LocationEntity;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 百度、高德定位
 *
 * @author wuhs 20151120
 */
public class LocationServiceUtil implements AMapLocationListener {
    private Utils utils;
    private LocationClient bdLocationManager = null;//百度管理类
    private LocationClientOption mOption, DIYoption;

//	private LocationManagerProxy gdLocationManagerProxy = null;//高德管理类

    /**
     * 高德修改
     */
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明AMapLocationClientOption对象
    public AMapLocationClientOption mLocationOption = null;

    private StartPwdActivity locationActivity;//回调的activity，可以写成接口，实现必要的回调方法，StartPwdActivity即可改为接口类
    private String locationType;
    private Object objLock = new Object();
    private Context mContext;
    private boolean BDServerError = false;//百度接口获取失败
    private boolean GDServerError = false;//高德接口获取失败
    private ProgressDialog mypDialog;
    private Dialog againDialog;

    /***
     * 构造方法1
     * @param locationContext
     */
    public LocationServiceUtil(Context locationContext, StartPwdActivity Activity) {
        synchronized (objLock) {
            //初始化百度服务
            if (bdLocationManager == null) {
                bdLocationManager = new LocationClient(locationContext);
                bdLocationManager.setLocOption(getDefaultLocationClientOption());
            }
            //初始化高德服务
//			if(gdLocationManagerProxy==null){
//				gdLocationManagerProxy = LocationManagerProxy.getInstance(locationContext);
//			}
            mContext = locationContext;
            locationActivity = Activity;
            Log.d("location", "初始化1");
        }
    }

    /***
     * 构造方法2
     * @param locationContext
     */
    public LocationServiceUtil(Context locationContext) {
        synchronized (objLock) {
            //初始化百度服务
            if (bdLocationManager == null) {
                bdLocationManager = new LocationClient(locationContext);
                bdLocationManager.setLocOption(getDefaultLocationClientOption());
            }
            //初始化高德服务
            if (mLocationClient == null) {
                mLocationClient = new AMapLocationClient(locationContext);
            }
            mContext = locationContext;
            Log.d("location", "初始化2");
            //locationActivity =new LocationActivity();
        }
    }

    /**
     * 外部开启定位接口
     *
     * @param location
     */
    public void startLocationService(StartPwdActivity location) {
        if (!utils.isNetworkConnected(location) && !utils.isWifiNetworkConnected(location)) {
            Toast.makeText(location, "连接网络异常，无法定位", Toast.LENGTH_SHORT).show();
        } else {
            locationActivity = location;
            mypDialog = ProgressDialog.show(locationActivity, "", "正在努力定位", false, true);
            initAgainDialog(locationActivity);
            setBDServerError(false);
            setGDServerError(false);
            startBDLocation();
            startGDLocation();
        }
    }

    /**
     * 外部关闭定位接口
     */
    public void stopLocationService() {
        if (mypDialog != null) {
            mypDialog.cancel();
        }
        locationActivity = null;
        setLocationType(null);

        stopBDLocation();
        stopGDLocation();
    }

    /**
     * 百度定位设置监听方法
     *
     * @param listener
     * @return
     */

    private boolean registerListener(BDLocationListener listener) {
        boolean isSuccess = false;
        if (listener != null) {
            bdLocationManager.registerLocationListener(listener);
            isSuccess = true;
        }
        return isSuccess;
    }

    /***
     * 百度定位取消监听方法
     * @param listener
     * @return
     */
    private void unregisterListener(BDLocationListener listener) {
        if (listener != null) {
            bdLocationManager.unRegisterLocationListener(listener);
        }
    }

    /***
     * 百度定位参数
     * @return DefaultLocationClientOption
     */
    private LocationClientOption getDefaultLocationClientOption() {
        if (mOption == null) {
            mOption = new LocationClientOption();
            mOption.setLocationMode(LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
            mOption.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系，如果配合百度地图使用，建议设置为bd09ll;
//			mOption.setScanSpan(60 * 1000);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
            mOption.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
            mOption.setIsNeedLocationDescribe(true);//可选，设置是否需要地址描述
            mOption.setNeedDeviceDirect(false);//可选，设置是否需要设备方向结果
            mOption.setLocationNotify(false);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
            mOption.setIgnoreKillProcess(true);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
            mOption.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
//			mOption.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
            mOption.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        }
        return mOption;
    }

    private void start() {
        synchronized (objLock) {
            if (bdLocationManager != null && !bdLocationManager.isStarted()) {
                bdLocationManager.start();
            }
        }
    }

    private void stop() {
        synchronized (objLock) {
            if (bdLocationManager != null && bdLocationManager.isStarted()) {
                bdLocationManager.stop();
            }
        }
    }

    /***
     * 设置百度定位参数
     * @param option
     * @return isSuccessSetOption
     */
    private boolean setLocationOption(LocationClientOption option) {
        boolean isSuccess = false;
        if (option != null) {
            if (bdLocationManager.isStarted())
                bdLocationManager.stop();
            DIYoption = option;
            bdLocationManager.setLocOption(option);
        }
        return isSuccess;
    }

    private LocationClientOption getOption() {
        return DIYoption;
    }

    /**
     * 停止百度定位
     */
    private void stopBDLocation() {
        this.unregisterListener(mListener); //注销掉监听
        this.stop(); //停止定位服务
        Log.d("location", "停止百度定位");
    }

    /**
     * 开启百度定位
     */
    private void startBDLocation() {
        // -----------location config ------------
        this.registerListener(mListener);
        this.setLocationOption(getDefaultLocationClientOption());
        this.start();// 定位SDK
        Log.d("location", "开启百度定位");
        // start之后会默认发起一次定位请求，开发者无须判断isstart并主动调用request
    }

    /*****
     * 自定义百度监听方法
     * 定位结果回调，重写onReceiveLocation方法，可以直接拷贝如下代码到自己工程中修改
     *
     */
    private BDLocationListener mListener = new BDLocationListener() {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // TODO Auto-generated method stub
            if (null != location
                    && location.getLocType() != BDLocation.TypeOffLineLocation
                    && location.getLocType() != BDLocation.TypeServerError
                    && location.getLocType() != BDLocation.TypeNetWorkException
                    && location.getLocType() != BDLocation.TypeCriteriaException) {
                Log.e("pm", "bd" + JSON.toJSONString(location));

                if (TextUtils.isEmpty(getLocationType())) {
                    setLocationType("百度");
                    Log.e("pm", "bd first");
                    stopGDLocation();//如果百度先定位成功，则主动停止高德定位
                }

                if (getLocationType().equals("百度")) {
                    stopGDLocation();//0，则主动停止高德定位
                    double mLongitude = location.getLongitude();
                    double mLatitude = location.getLatitude();

                    String mBaseLocation = null;
                    String mWifiLocation = null;
                    String mGpsLocation = null;
                    String province = location.getProvince();
                    String province_loc = location.getProvince();
                    String city = location.getCity();
                    String city_loc = location.getCity();
                    String district = location.getDistrict();
                    String district_loc = location.getDistrict();
                    String street = location.getStreet();
                    String locationType = "百度";
                    String locationTime = location.getTime();

                    if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                        mGpsLocation = location.getAddrStr();
                    } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                        if (Utils.isWifiNetworkConnected(mContext)) {// wifi
                            mWifiLocation = location.getAddrStr();
                        } else {
                            mBaseLocation = location.getAddrStr();
                        }
                    }
                    LocationEntity locationEntity = new LocationEntity(mLongitude, mLatitude, mBaseLocation, mWifiLocation, mGpsLocation, province, city, district, street, province_loc, city_loc, district_loc, locationType, locationTime);
                    //回调
                    if (locationActivity != null && getLocationType().equals("百度")) {
                        mypDialog.cancel();//关闭mypDialog
                        locationActivity.onActivityLocationService(locationEntity);
                    }
                } else {
                    return;
                }
            } else {
                if (isGDServerError()) {//判断是否另一接口是否也失败
                    mypDialog.cancel();//关闭mypDialog
                    againDialog.show();
                }
                setBDServerError(true);
            }
        }

    };

    /**
     * 开启高德定位
     */
    private void startGDLocation() {

        // 初始化定位，只采用网络定位
        // mLocationManagerProxy = LocationManagerProxy.getInstance(this);
        // mLocationManagerProxy.setGpsEnable(false);
        // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
        // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用removeUpdates()方法来取消定位请求
        // 在定位结束后，在合适的生命周期调用destroy()方法
        // 其中如果间隔时间为-1，则定位只定一次,
        // 在单次定位情况下，定位无论成功与否，都无需调用removeUpdates()方法移除请求，定位sdk内部会移除
        //初始化AMapLocationClientOption对象
        mLocationOption = new AMapLocationClientOption();
        mLocationOption.setOnceLocation(true);
        mLocationClient.setLocationOption(mLocationOption);
        mLocationClient.setLocationListener(this);
        //启动定位
        mLocationClient.startLocation();
//				requestLocationData(
//				LocationProviderProxy.AMapNetwork,-1 /*60 * 1000*/, 15, this);
        Log.d("location", "开启高德定位");
    }

    /**
     * 停止高德定位
     */
    private void stopGDLocation() {
        mLocationClient.unRegisterLocationListener(this);
        // 移除定位请求
        mLocationClient.stopLocation();
        // 销毁定位
//		mLocationClient.onDestroy();
        Log.d("location", "停止高德定位");
    }

    /**
     * 高德定位回调方法
     *
     * @param amapLocation
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        LogUtil.e("pm", "AMapLocation=" + JSON.toJSONString(amapLocation));

        if (amapLocation != null && amapLocation.getErrorCode() == 0) {

            Log.e("pm", "gd" + JSON.toJSONString(amapLocation));

            if (TextUtils.isEmpty(getLocationType())) {
                Log.e("pm", "gd first");
                setLocationType("高德");
                stopBDLocation();//如果高德先定位成功，则主动停止百度定位
            }

            if (getLocationType().equals("高德")) {

                stopBDLocation();//如果高德先定位成功，则主动停止百度定位
                double mLongitude = /*30.339580*/amapLocation.getLongitude();
                double mLatitude = /*113.08547*/amapLocation.getLatitude();

                String mBaseLocation = null;
                String mWifiLocation = null;
                String mGpsLocation = null;
                String province = amapLocation.getProvince();
                String province_loc = amapLocation.getProvince();
                String city = amapLocation.getCity();
                String city_loc = amapLocation.getCity();
                String district = amapLocation.getDistrict();
                String district_loc = amapLocation.getDistrict();
                String street = amapLocation.getRoad();
                String locationType = "高德";
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new Date(amapLocation.getTime());
                String locationTime = df.format(date);

                if (amapLocation.getProvider().equals("lbs")) {
                    if (Utils.isWifiNetworkConnected(mContext)) {// wifi
                        mWifiLocation = amapLocation.getAddress();
                    } else {
                        mBaseLocation = amapLocation.getAddress();
                    }
                } else if (amapLocation.getProvider().equals("gps")) {
                    mGpsLocation = amapLocation.getAddress();
                }

                LocationEntity locationEntity = new LocationEntity(mLongitude, mLatitude, mBaseLocation, mWifiLocation,
                        mGpsLocation, province, city, district, street, province_loc, city_loc, district_loc, locationType, locationTime);
                //回调
                if (locationActivity != null && getLocationType().equals("高德")) {
                    mypDialog.cancel();//关闭mypDialog
                    locationActivity.onActivityLocationService(locationEntity);
                }
            } else {
                return;
            }
        } else {
            if (isBDServerError()) {//判断是否另一接口是否也失败
                mypDialog.cancel();//关闭mypDialog
                againDialog.show();
            }
            setGDServerError(true);
        }
    }


    /**
     * 自定义ProgressDialog参数
     */
    private void showProgressDialog(Activity activity) {

        mypDialog = new ProgressDialog(activity);
        //实例化
        mypDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        //设置进度条风格，风格为圆形，旋转的
//		mypDialog.setTitle("正在定位");
        //设置ProgressDialog 标题
        mypDialog.setMessage("正在努力定位");
        //设置ProgressDialog 提示信息
//		mypDialog.setIcon(R.drawable.);
        //设置提示的title的图标，默认是没有的，如果没有设置title的话只设置Icon是不会显示图标的
//		mypDialog.setButton("Google",this);
        //设置ProgressDialog 的一个Button
        mypDialog.setIndeterminate(false);
        //设置ProgressDialog 的进度条是否不明确
        mypDialog.setCancelable(true);
        //设置ProgressDialog 是否可以按退回按键取消
        mypDialog.setCanceledOnTouchOutside(true);// 设置在点击Dialog外是否取消Dialog进度条
        mypDialog.show();
        //让ProgressDialog显示
    }

    /**
     * 自定义弹出框
     *
     * @param activity
     */
    protected void initAgainDialog(final Activity activity) {

        AlertDialog.Builder againBuilder = new Builder(activity);

        againBuilder.setMessage("定位不给力，再试试?");

        againBuilder.setTitle("非常遗憾");

        againBuilder.setPositiveButton("再来一次", new OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                mypDialog = ProgressDialog.show(activity, "", "正在努力定位",
                        false, true);

//				setBDServerError(false);
//				setGDServerError(false);
                startBDLocation();
                startGDLocation();
                dialog.dismiss();

            }

        });

        againBuilder.setNegativeButton("取消", new OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                stopBDLocation();
                stopGDLocation();
                dialog.dismiss();

            }

        });
        againDialog = againBuilder.create();
    }


    //============================华丽的分割线  getset方法====================================================
    /*
     * synchronized修饰，保持字段唯一性
	 */
    public synchronized String getLocationType() {
        return locationType;
    }

    public synchronized void setLocationType(String locationType) {
        this.locationType = locationType;
    }


    public synchronized boolean isBDServerError() {
        return BDServerError;
    }

    public synchronized void setBDServerError(boolean bDServerError) {
        BDServerError = bDServerError;
    }

    public synchronized boolean isGDServerError() {
        return GDServerError;
    }

    public synchronized void setGDServerError(boolean gDServerError) {
        GDServerError = gDServerError;
    }
}
